# Paths
Binaries	= Binaries
Libraries	= $(Binaries)/Libraries
StaticLibs	= $(Libraries)/Static
SharedLibs	= $(Libraries)/Shared
ObjectFiles	= $(Binaries)/ObjectFiles
Executables	= $(Binaries)/Executables
Report		= Report
Graphics	= $(Report)/Graphics
TeX			= $(Report)/TeX
GeneratedTeX = $(TeX)/Generated
DoxygenGenerated = $(GeneratedTeX)/Doxygen
AdditionalHeadersPath = /Users/Andrey/Karma/Sources/C/Utilities
UtilitiesPath = /Users/Andrey/Karma/Utilities

# Utilities
Kompiler = gcc -I$(AdditionalHeadersPath) -std=c99 -g
VerboseKompiler = $(Kompiler) -v
# DebugKompiler = $(Kompiler) -g
LibTool = libtool
Graphviz = /usr/local/bin/dot -Tpng
DotToTeX = /usr/local/bin/dot2tex -ftikz  --crop --autosize
DotToTeXForFigures = /usr/local/bin/dot2tex -ftikz --figonly
Flex = flex -i
Bison = /usr/local/bin/bison -d -t 
VerboseBison = $(Bison) -v
Doxygen = doxygen doxygen.cfg
CFlow = cflow --level "0= "
FlowFilter = grep -v -f cflow.ignore
CFlowToDot = $(UtilitiesPath)/cflow2dot
PdfLatex = pdflatex -interaction=nonstopmode
MakeFileToDot = $(UtilitiesPath)/makefile2dot

.PHONY: NetTalk ClientDispatch TLog SmtpFSM clean Maildir Report

all: MinimalSmtp

clean:
	rm -rf $(ObjectFiles)/* $(Executables)/* $(GeneratedTeX)/* $(Graphics)/*
	rm -f *.o
	mkdir -p $(DoxygenGenerated)

Directories:
	mkdir $(Binaries)
	mkdir -p $(Libraries)
	mkdir -p $(StaticLibs)
	mkdir -p $(SharedLibs)
	mkdir -p $(ObjectFiles)
	mkdir -p $(Executables)
	mkdir $(Report)
	mkdir -p $(Graphics)
	mkdir -p $(TeX)
	mkdir -p $(GeneratedTeX)
	mkdir -p $(DoxygenGenerated)

# Building without libs

MinimalSmtp: Maildir SmtpFSM SmtpUtility SmtpCommandsParser MinimalSmtpExecutable

# Command line option parsing
CommandLineOptionsParser:
	cd MinimalSmtp && autogen CommandLineOptions.def
#	$(Kompiler)

# Maildir
Maildir:
	$(Kompiler) -c Maildir/Maildir.c
	mv *.o $(ObjectFiles)

# Protocol FSM

SmtpFSM: SmtpFSMSourceFiles SmtpFSMGraphics
	mv *.o $(ObjectFiles)

SmtpFSMGraphics:
	cfsm -g -o $(Graphics)/Smtp.dot Smtp/Smtp.fsm
	
SmtpFSMSourceFiles:
	cfsm -d -o Smtp/SmtpFsm.c Smtp/Smtp.fsm
	patch Smtp/SmtpFsm.c Smtp/FixWrongInclude.patch
	$(Kompiler) -c Smtp/SmtpFsm.c

# Protocol utility functions
SmtpUtility:
	$(Kompiler) -c Smtp/Smtp.c Smtp/SmtpReplies.c
	mv *.o $(ObjectFiles)

# Protocol commands
SmtpCommandsParser: NetTalk TLog ClientDispatch SmtpCommandsLexer
	$(VerboseBison) -g -o Smtp/SmtpCommandsParser.c Smtp/SmtpCommands.y
	$(Kompiler) -c Smtp/SmtpCommandsLexer.c Smtp/SmtpCommandsParser.c 
#	$(VerboseBison) -g -o Smtp/SmtpCommandsParser.c Smtp/SmtpCommandsDebug.y
#	$(Kompiler) -c Smtp/SmtpCommandsLexer.c Smtp/SmtpCommandsParser.c
	mv *.o $(ObjectFiles)
#	$(Kompiler) Smtp/SmtpCommandsLexer.c Smtp/SmtpCommandsParser.c $(ObjectFiles)/DataBuffer.o $(ObjectFiles)/ClientDispatchLog.o $(ObjectFiles)/tlog.o -o $(Executables)/SmtpCommandsParser
	
SmtpCommandsLexer:
	$(Flex) -o Smtp/SmtpCommandsLexer.c Smtp/SmtpTokens.l
#	$(Kompiler) Smtp/SmtpCommandsLexer.c -o Smtp/SmtpCommandsLexer -lfl
#	$(Flex) -d -o Smtp/SmtpCommandsLexer.c Smtp/SmtpTokensDebug.l

# Sources
MinimalSmtpExecutable: TLog NetTalk ClientDispatch
	$(Kompiler) -c MinimalSmtp/MinimalSmtp.c
	mv *.o $(ObjectFiles)
	$(Kompiler) -levent -o $(Executables)/MinimalSmtp $(ObjectFiles)/*

ClientDispatchTest: TLog NetTalk ClientDispatch
	$(Kompiler) -c ClientDispatchTest/main.c
	mv *.o $(ObjectFiles)
	$(Kompiler) -levent -o $(Executables)/ClientDispatchTest $(ObjectFiles)/*

TLog:
	$(Kompiler) -c TLog/tlog.c

NetTalk:
	$(Kompiler) -c NetTalk/DataBuffer.c NetTalk/BsdSocketAbstractionLayer.c NetTalk/NetTalkClientMap.c NetTalk/NetTalk.c
	
ClientDispatch:
	$(Kompiler) -c ClientDispatch/ClientList.c ClientDispatch/ClientQueue.c ClientDispatch/WorkerThreadPool.c ClientDispatch/ClientDispatchLog.c ClientDispatch/ClientDispatch.c $(ObjectFiles)/Smtp.o
	
# Documentation
Report: SmtpFSMGraphics FlowChart Documentation
	$(DotToTeXForFigures) $(Graphics)/Smtp.dot > $(GeneratedTeX)/Smtp.gv.tex
	cd $(TeX) && $(PdfLatex) Report.tex

Documentation:
	$(Doxygen)
	cd $(DoxygenGenerated)/latex && make all
	
FlowChart:
	$(CFlow) NetTalk/*.c | $(CFlowToDot) | $(DotToTeX) > $(GeneratedTeX)/NetTalk.tex
	cd $(GeneratedTeX) && $(PdfLatex) NetTalk.tex
	$(CFlow) ClientDispatch/*.c | $(CFlowToDot) | $(DotToTeX) > $(GeneratedTeX)/ClientDispatch.tex
	cd $(GeneratedTeX) && $(PdfLatex) ClientDispatch.tex
	$(CFlow) Smtp/*.c | $(CFlowToDot) | $(DotToTeX) > $(GeneratedTeX)/Smtp.tex
	cd $(GeneratedTeX) && $(PdfLatex) Smtp.tex
#	$(CFlow) NetTalk/*.c | $(CFlowToDot) > $(GeneratedTeX)/NetTalk.cflow.dot
#	$(CFlow) ClientDispatch/*.c | $(CFlowToDot) > $(GeneratedTeX)/ClientDispatch.cflow.dot
#	$(CFlow) Smtp/*.c | $(CFlowToDot) > $(GeneratedTeX)/Smtp.cflow.dot
#	$(MakeFileToDot) MinimalSmtp
